﻿Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Imports System.IO.IsolatedStorage
Imports Runa.Foundation.Threading
Imports Runa.Core.Services
Imports Runa.UI.Threading
Imports Runa.Common.Helper
Imports System.Collections
Imports MS.Internal.Threading
Imports Runa.Foundation.Messaging
Imports Runa.UI.Controls

Partial Public Class GameRender
    Implements ISafeNativeMethods

    Public Property Timers As New List(Of Tuple(Of DateTime, Win32Timer)) Implements ISafeNativeMethods.Timers
    Public Property Hwnds As New List(Of IMessageFilter) Implements ISafeNativeMethods.Hwnds

    Public Sub KillTimer(ByVal hwnd As Integer, ByVal nIDEvent As Integer) Implements ISafeNativeMethods.KillTimer
        Dim ts = (From item In Me.Timers Where item.Item2.Hwnd = hwnd Select item).ToList()
        SyncLock Me.Timers
            ts.RemoveIf(Function(item) item.Item2.Hwnd = hwnd And item.Item2.Interval = nIDEvent)
        End SyncLock
    End Sub

    Public Sub SetTimer(ByVal hwnd As Integer, ByVal nIDEvent As Integer, ByVal interval As Integer, Optional ByVal callback As TickEventHandler = Nothing) Implements ISafeNativeMethods.SetTimer
        SyncLock Me.Timers
            Dim timer = New Win32Timer(hwnd, nIDEvent, interval, callback)
            AddHandler timer.Tick,
                Sub(sender, e)
                    Me.SendMessage(timer.Hwnd, Message.Create(Dispatcher.FromThread(timer.Hwnd), MessageType.WM_TIMER, Nothing, timer.EventID))
                End Sub
            Me.Timers.Add(New Tuple(Of DateTime, Win32Timer)(DateTime.Now, timer))
        End SyncLock
    End Sub

    Private Sub UpdateTimers(gameTime As Runa.Foundation.Runtime.GameTimeEventArgs) Implements ISafeNativeMethods.UpdateTimers
        SyncLock Me.Timers
            For Each item In Me.Timers
                Dim delta = DateTime.Now - item.Item1
                If item.Item2 Is Nothing Then Me.Timers.Remove(item) : Continue For
                If item.Item2.Invalid = True Then Me.Timers.Remove(item) : Continue For
                If CInt(delta.TotalMilliseconds) Mod item.Item2.Interval = 0 Then
                    item.Item2.FireTick(delta)
                End If
            Next
        End SyncLock
    End Sub

    Public Function RegisterWindowClass(hwnd As Runa.Foundation.Messaging.IMessageFilter) As Boolean Implements ISafeNativeMethods.RegisterWindowClass
        SyncLock Me.Hwnds
            Me.Hwnds.Add(hwnd)
            Return True
        End SyncLock
    End Function

    Public Function UnRegisterWindowClass(hwnd As IMessageFilter) As Boolean Implements ISafeNativeMethods.UnRegisterWindowClass
        SyncLock Me.Hwnds
            Me.Hwnds.Remove(hwnd)
            If TypeOf hwnd Is UIElementBase Then
                For Each item In CType(hwnd, UIElementBase).Children
                    Try
                        Me.Hwnds.Remove(item)
                    Catch ex As Exception
                        Continue For
                    End Try
                Next
            End If
            If TypeOf hwnd Is ContentControl Then
                Me.Hwnds.Remove(CType(hwnd, ContentControl).Content)
            End If
            Return True
        End SyncLock
    End Function

    Public Function RegisterWindowMessage(name As String, value As Integer) As Boolean Implements ISafeNativeMethods.RegisterWindowMessage
        Try
            SyncLock Me.MessageHandlers
                Me.MessageHandlers.Add(name, CType(value, MessageType))
                Return True
            End SyncLock
        Catch ex As Exception
            Return False
        End Try
    End Function

End Class